package org.lwjgl.demo.device;

/**
 * 相机类
 *
 * @author zhoudy
 * @date 2025/10/29 21:52
 */
import org.joml.Matrix4f;
import org.joml.Vector3f;

import static org.lwjgl.glfw.GLFW.*;

// ==================== 修改：扩展相机类支持WASD移动 ====================
public class Camera {
    private Vector3f position;
    private Vector3f front;
    private Vector3f up;
    private Vector3f right;
    private Vector3f worldUp;

    private float yaw = -90.0f;
    private float pitch = 0.0f;

    // ==================== 新增：相机移动参数 ====================
    private float movementSpeed = 2.5f;
    private float mouseSensitivity = 0.1f;

    public Camera(Vector3f position, Vector3f up) {
        this.position = position;
        this.worldUp = up;
        updateCameraVectors();
    }

    public Matrix4f getViewMatrix() {
        return new Matrix4f().lookAt(position,
                new Vector3f(position).add(front), up);
    }

    // ==================== 新增：处理键盘输入 ====================
    public void processKeyboard(int direction, float deltaTime) {
        float velocity = movementSpeed * deltaTime;

        switch (direction) {
            case GLFW_KEY_W: // 前进
                position.add(new Vector3f(front).mul(velocity));
                break;
            case GLFW_KEY_S: // 后退
                position.sub(new Vector3f(front).mul(velocity));
                break;
            case GLFW_KEY_A: // 左移
                position.sub(new Vector3f(right).mul(velocity));
                break;
            case GLFW_KEY_D: // 右移
                position.add(new Vector3f(right).mul(velocity));
                break;
        }
    }

    public void processMouseMovement(float xOffset, float yOffset) {
        xOffset *= mouseSensitivity;
        yOffset *= mouseSensitivity;

        yaw += xOffset;
        pitch += yOffset;

        if (pitch > 89.0f) pitch = 89.0f;
        if (pitch < -89.0f) pitch = -89.0f;

        updateCameraVectors();
    }

    private void updateCameraVectors() {
        Vector3f newFront = new Vector3f();
        newFront.x = (float) (Math.cos(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)));
        newFront.y = (float) Math.sin(Math.toRadians(pitch));
        newFront.z = (float) (Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)));
        front = newFront.normalize();

        right = new Vector3f(front).cross(worldUp).normalize();
        up = new Vector3f(right).cross(front).normalize();
    }

    // ==================== 新增：Getter方法 ====================
    public Vector3f getPosition() { return position; }
    public Vector3f getFront() { return front; }
    public Vector3f getUp() { return up; }

    // ==================== 新增：设置移动速度 ====================
    public void setMovementSpeed(float speed) {
        this.movementSpeed = speed;
    }
}
